<!--
 * @Author: haibo haibo.yang@lgmgim.cn
 * @Date: 2022-06-08 13:27:20
 * @LastEditors: haibo haibo.yang@lgmgim.cn
 * @LastEditTime: 2022-06-22 21:14:08
 * @FilePath: /HttpServer/HttpServer/templates/mapping.html
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Mapping</title>
    <link rel="icon" href="{{ url_for('static',filename='img/favicon.ico') }}">
    <link href="{{ url_for('static',filename='css/bootstrap.min.css') }}" rel="stylesheet">
    <link rel="stylesheet" href="{{ url_for('static',filename='css/w3.css') }}" />
    <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='font-awesome-4.7.0/css/font-awesome.min.css')}}">

    <script type="text/javascript" src="{{ url_for('static',filename='lib/EaselJS/lib/easeljs.min.js') }}"></script>
    <script type="text/javascript" src="{{ url_for('static',filename='lib/eventemitter2.min.js') }}"></script>
    <script type="text/javascript" src="{{ url_for('static',filename='lib/roslibjs/build/roslib.min.js') }}"></script>

    <script type="text/javascript" src="{{ url_for('static', filename='lib/ros2d.js') }}"></script>
    <script type="text/javascript" src="{{ url_for('static', filename='lib/NavGoal.js') }}"></script>
    <script type="text/javascript" src="{{ url_for('static', filename='lib/NavPath.js') }}"></script>
    <script type="text/javascript" src="{{ url_for('static', filename='lib/PoseAndTrace.js') }}"></script>
    <script src="{{ url_for('static',filename='js/jquery.min.js') }}"></script>
    <script src="{{ url_for('static',filename='js/bootstrap.min.js') }}"></script>
    <script type="text/javascript" type="text/javascript">
        var MAP_WIDTH = (window.innerWidth) * 0.8;
        var MAP_HEIGHT = MAP_WIDTH;
        robotvisible = true;

        /**
         * Setup all visualization elements when the page is loaded.
         */
        function init() {
            // Connect to ROS.
            var ros = new ROSLIB.Ros({
                //url: 'ws://192.168.0.109:19000'
                url: 'ws://192.168.8.82:19000'
                //url: 'ws://192.168.8.74:19000'
                //url: 'ws://192.168.127.129:19000'
            });

            ros.on('error', function (error) {
                console.log(error);
                var state =  document.getElementById("connect");
                state.innerHTML = "Error!";
                state.style.color = "red";
            });
            // Find out exactly when we made a connection.
            ros.on('connection', function () {
                console.log('Connection made!');
                var state =  document.getElementById("connect");
                state.innerHTML = "Conneted!";
                state.style.color = "green";
            });

            ros.on('close', function () {
                console.log('Connection closed.');
                var state =  document.getElementById("connect");
                state.innerHTML = "Close!";
                state.style.color = "yellow";
            });

            // Create the main viewer.
            var viewer = new ROS2D.Viewer({
                divID: 'map',
                width: MAP_WIDTH,
                height: MAP_HEIGHT
            });

            // Setup the map client.
            var gridClient = new ROS2D.OccupancyGridClient({
                ros: ros,
                rootObject: viewer.scene,
                // Use this property in case of continuous updates			
                continuous: true
            });

            // Scale the canvas to fit to the map
            gridClient.on('change', function () {
                viewer.scaleToDimensions(gridClient.currentGrid.width, gridClient.currentGrid.height);
                viewer.shift(gridClient.currentGrid.pose.position.x, gridClient.currentGrid.pose.position.y);
            });

            var robotMarker = new ROS2D.NavigationArrow({
                size: 1,
                strokeSize: 0.01,
                strokeColor: createjs.Graphics.getRGB(0, 0, 255, 0.66),
                fillColor: createjs.Graphics.getRGB(0, 255, 0, 0.66),
                pulse: false
            });
            viewer.scene.addChild(robotMarker);

            var traceShape = new ROS2D.TraceShape({
                strokeSize: 0.01,
                strokeColor: createjs.Graphics.getRGB(255, 0, 0, 1),
                maxPoses: 250
            });
            viewer.scene.addChild(traceShape);

            var odomFB = new ROSLIB.Topic({
                ros: ros,
                name: '/base/twist_controller/odom',
                messageType: 'nav_msgs/Odometry'
            });

            //update on new message
            odomFB.subscribe(function (message) {
                traceShape.addPose(message.pose.pose);
                robotMarker.x = message.pose.pose.position.x;
                robotMarker.y = -message.pose.pose.position.y;

                robotMarker.rotation = robotMarker.stage.rosQuaternionToGlobalTheta(message.pose.pose.orientation);

                document.getElementById('vehiclePose').innerHTML = "坐标(x:" + Math.round(robotMarker.x * 100) / 100
                    + " y:" + Math.round(robotMarker.y * 100) / 100 + " yaw:" + Math.round(robotMarker.rotation * 100) / 100 + ")";
           
            });

             // Add zoom to the viewer.
            var zoomView = new ROS2D.ZoomView({
                rootObject: viewer.scene
            });
            // Add panning to the viewer.
            var panView = new ROS2D.PanView({
                rootObject: viewer.scene
            });

            // Setup mouse event handlers
            var mouseDown = false;
            var zoomKey = false;
            var panKey = false;
            var startPos = new ROSLIB.Vector3();
            // EVENT: Mouse DOWN
            viewer.scene.addEventListener('stagemousedown', function (event) {
                if (event.nativeEvent.ctrlKey === true) {
                    //console.log("Ctrl + Mouse");
                    zoomKey = true;
                    zoomView.startZoom(event.stageX, event.stageY);
                }
                else if (event.nativeEvent.shiftKey === true) {
                    //console.log("Shift + Mouse");
                    panKey = true;
                    panView.startPan(event.stageX, event.stageY);
                }
                
                startPos.x = event.stageX;
                startPos.y = event.stageY;
                //console.log("startPos.x: " + startPos.x);
                //console.log("startPos.y: " + startPos.y);

                mouseDown = true;
            });
            // EVENT: Mouse MOVE
            viewer.scene.addEventListener('stagemousemove', function (event) {
                if (mouseDown === true) {
                    if (zoomKey === true) {
                        var dy = event.stageY - startPos.y;
                        var zoom = 1 + 10 * Math.abs(dy) / viewer.scene.canvas.clientHeight;
                        if (dy < 0)
                            zoom = 1 / zoom;
                        zoomView.zoom(zoom);
                    }
                    else if (panKey === true) {
                        panView.pan(event.stageX, event.stageY);
                    }
                }
            });
            // EVENT: Mouse UP
            viewer.scene.addEventListener('stagemouseup', function (event) {
                if (mouseDown === true) {
                    if (zoomKey === true) {
                        zoomKey = false;
                    }
                    else if (panKey === true) {
                        panKey = false;
                    }
                    mouseDown = false;
                }
            });
        }
    </script>
</head>

<body onload="init()">

    <div class="w3-top">
        <div class="w3-bar w3-white w3-card">
            <a href="#" class="w3-bar-item w3-button w3-wide"><i class="fa fa-map"></i>建图</a>
            <div class="w3-right w3-hide-small">
                <a href="#" class="w3-bar-item w3-button"><i class="fa fa-list"></i>参数</a>
                <a href="{{ url_for('home.index') }}" class="w3-bar-item w3-button"><i class="fa fa-paper-plane"></i>导航</a>
                <a class="w3-bar-item w3-button" data-toggle="modal" data-target="#myModal"><i class="fa fa-save"></i>保存</a>
                </ul>
            </div>
        </div>
    </div>

    <div class="w3-container w3-light-grey" style="padding:44px 8px">
        <div class="w3-row-padding">
            <div class="w3-col m6">
                <div id="map" style="display:inline-block;"></div>
            </div>
        </div>
    </div>

    <div class="w3-container w3-white w3-card">
        <div class="w3-row-padding">
            <div class="w3-container w3-cell">
                <p id="connect" style="color:#d60024;"> Disconnected</p>
            </div>
            <div class="w3-container w3-cell">
                <p id="vehiclePose"></p>
            </div>
            <div class="w3-container w3-cell">
                <p id="Pose"></p>
            </div>
        </div>
    </div>

    <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h4 class="modal-title" id="myModalLabel">
                        保存文件
                    </h4>
                </div>
                <div class="modal-body">
                    <form method="post" action="/savemap">
                        <input id='filename' class="form-control" name="filename" placeholder="文件名" type="text">
                        <button id='savefile' class="btn btn-primary" type="submit">保存</button>
                    </form>
                </div>
            </div>
        </div>
    </div>
</body>

</html>